home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 12.1 KB | 392 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: Part.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
- //
- // Keywords to search for:
- //
- // MUSTCHANGE Some constants which *must* be changed by you.
- // CONTENTDATA Simple text model; you will want to change this as well.
- //
- // CYBERDOG Standard Cyberdog/ODF recipes.
- // USETHREADSFLAG Some threaded stuff; not finished in this version.
- //
-
- #ifndef PART_H
- #include "Part.h"
- #endif
-
- #ifndef FRAME_H
- #include "Frame.h"
- #endif
-
- #ifndef DEFINE_H
- #include "Define.h"
- #endif
-
- #ifndef BINDING_H
- #include "Binding.h"
- #endif
-
- #ifndef FWCONTXT_H
- #include "FWContxt.h"
- #endif
-
- #ifndef FWITERS_H
- #include "FWIters.h"
- #endif
-
- #ifndef FWCYSTRM_H
- #include "FWCyStrm.h"
- #endif
-
- #ifndef SOM_CyberStream_xh
- #include <CyberStream.xh>
- #endif
-
- #ifndef SOM_CyberItem_xh
- #include <CyberItem.xh>
- #endif
-
- #ifndef FWSUSINK_H
- #include "FWSUSink.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- #ifndef FWMNUBAR_H
- #include "FWMnubar.h"
- #endif
-
- #ifndef FWCFMRES_H
- #include "FWCFMRes.h"
- #endif
-
- #ifndef _STORUTIL_
- #include <StorUtil.h>
- #endif
-
- #ifndef SOM_Module_OpenDoc_StdProps_defined
- #include <StdProps.xh>
- #endif
-
- // ----- Cyberdog Support-----
-
- #ifndef __CYBERDOG__
- #include <Cyberdog.h>
- #endif
-
- #ifndef SOM_CyberSession_xh
- #include <CyberSession.xh>
- #endif
-
- #include <stdio.h>
-
- //========================================================================================
- //
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment CPart
- #endif
-
- //========================================================================================
- // Class CPart
- //========================================================================================
-
- FW_DEFINE_AUTO(CPart)
-
- //----------------------------------------------------------------------------------------
- // ImmediateRedrawPresentation
- //----------------------------------------------------------------------------------------
-
- static void ImmediateRedrawPresentation (Environment* ev, FW_CPresentation* p)
- {
- FW_CPresentationFrameIterator piter (ev, p);
- for (FW_CFrame* frame = piter.First(ev); piter.IsNotComplete(ev); frame = piter.Next(ev)) {
- FW_CFrameFacetIterator fiter (ev, frame);
- for (ODFacet* facet = (ODFacet*) fiter.First(ev); fiter.IsNotComplete(ev); facet = fiter.Next(ev)) {
- FW_CViewContext gc (ev, frame, facet, nil);
- ((CFrame*)frame)->DrawUpdate (ev, gc);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::CPart
- //----------------------------------------------------------------------------------------
-
- CPart::CPart(ODPart* odPart) :
- FW_CPart(odPart, FW_gInstance, kPartInfoID),
- fCyberdogHelper (nil), // Cyberdog
- #if !USETHREADSFLAG
- FW_CIdler (this, 10), // idling 6 times a second; this is a nice polite value
- fStream (nil),
- #endif
- fDownloadedText (nil),
- fAutoReload (true)
- {
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::CPart
- //----------------------------------------------------------------------------------------
-
- CPart::~CPart()
- {
- ::DisposeHandle (fDownloadedText);
- FW_START_DESTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::Initialize
- //----------------------------------------------------------------------------------------
-
- void CPart::Initialize(Environment* ev, ODStorageUnit* storageUnit, FW_Boolean fromStorage)
- {
- FW_CPart::Initialize (ev, storageUnit, fromStorage);
-
- // Cyberdog
- fCyberdogHelper = FW_SupportCyberdogIfPresent (ev, this, FW_kUseCyberMenus, kCyberdogCommands, FW_kUseNavigator);
- if (fCyberdogHelper)
- fCyberdogHelper->SetLoadCyberItemThreadProcedure (&LoadCyberItem, this);
-
- // All our frames look the same (just 1 presentation)
- fPresentation = RegisterPresentation(ev, kODPresDefault, TRUE);
-
- // Our content is just a block of text
- fDownloadedText = ::NewHandle(0);
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::NewFrame
- //----------------------------------------------------------------------------------------
-
- FW_CFrame* CPart::NewFrame(Environment* ev,
- ODFrame* odFrame,
- FW_CPresentation* presentation,
- FW_Boolean fromStorage)
- {
- FW_UNUSED(presentation);
- FW_UNUSED(fromStorage);
-
- return FW_NEW(CFrame, (ev, odFrame, presentation, this));
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::NewPartContent
- //----------------------------------------------------------------------------------------
-
- FW_CContent* CPart::NewPartContent(Environment* ev)
- {
- FW_UNUSED(ev);
- return NULL;
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::ExternalizeContent
- //----------------------------------------------------------------------------------------
-
- void CPart::ExternalizeContent (Environment* ev, ODStorageUnit* su, FW_CCloneInfo* cloneInfo)
- {
- FW_UNUSED(cloneInfo);
- // Before calling ExternalizeContent, FW_CODPart calls PrivCleanseContentProperty.
- // FW_CPart::ExternalizeContent then calls ClearPartStorage. These amount to an
- // expensize ODSURemoveProperty. RFE
- ODSURemoveProperty (ev, su, kODPropContents);
-
- {
- // Save content. Pure text, no other data, to make sure our data can be read by any other part.
- ODSUForceFocus (ev, su, kODPropContents, kKind);
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kKind);
- FW_CAcquireLockedSystemHandle locked (fDownloadedText);
- sink->Write (ev, *fDownloadedText, GetHandleSize(fDownloadedText));
- }
-
- {
- // Also save our preferences (auto-reload flag)
- ODSUForceFocus (ev, su, kODPropContents, kSettingsKind);
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kSettingsKind);
- FW_CWritableStream s (sink);
- s << fAutoReload;
- }
-
- if (fCyberdogHelper && fCyberdogHelper->GetCyberItem(ev)) {
- // Save our CyberItem so we can reload ourself later
- // Cyberdog defines the kCyberItemKind constant
- ODSUForceFocus (ev, su, kODPropContents, kCyberItemKind);
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kCyberItemKind);
- fCyberdogHelper->ExternalizeCurrentCyberItem (ev, sink);
- }
- else
- printf ("Can't find a CyberItem\n");
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::InternalizeContent
- //----------------------------------------------------------------------------------------
-
- FW_Boolean CPart::InternalizeContent(Environment* ev, ODStorageUnit* su, FW_CCloneInfo* cloneInfo)
- {
- FW_UNUSED(cloneInfo);
- // Read our content (if any).
- if (ODSUExistsThenFocus (ev, su, kODPropContents, kKind)
- /*|| ODSUExistsThenFocus (ev, su, kODPropContents, FW_CPart::fgMacTEXTDataType)*/)
- {
- Size size = su->GetSize (ev);
- ::SetHandleSize (fDownloadedText, size);
- FW_CAcquireLockedSystemHandle locked (fDownloadedText);
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kKind);
- sink->Read (ev, *fDownloadedText, size);
- }
- // Read our settings (the "auto-download" flag)
- if (ODSUExistsThenFocus (ev, su, kODPropContents, kSettingsKind)) {
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kSettingsKind);
- FW_CReadableStream s (sink);
- s >> fAutoReload;
- }
- // Read the CyberItem
- if (fCyberdogHelper && ODSUExistsThenFocus (ev, su, kODPropContents, kCyberItemKind)) {
- FW_PStorageUnitSink sink (ev, su, kODPropContents, kCyberItemKind);
- CyberItem* ci = fCyberdogHelper->InternalizeCyberItem (ev, sink, fAutoReload);
- }
- else
- printf ("Can't find a CyberItem\n");
-
- return true;
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::DoAdjustMenus
- //----------------------------------------------------------------------------------------
-
- FW_Handled CPart::DoAdjustMenus(Environment* ev, FW_CMenuBar* menuBar, FW_Boolean hasMenuFocus, FW_Boolean isRoot)
- {
- FW_UNUSED(isRoot);
- if (!hasMenuFocus)
- return FW_kNotHandled;
-
- if (fCyberdogHelper) {
- menuBar->EnableAndCheckCommand (ev, kAutoReload, TRUE, fAutoReload);
- menuBar->EnableCommand (ev, kDoReload, fCyberdogHelper->GetCyberItem(ev) != kODNULL);
- }
-
- return FW_kNotHandled;
- }
-
- //----------------------------------------------------------------------------------------
- // CPart::DoMenu
- //----------------------------------------------------------------------------------------
-
- FW_Handled CPart::DoMenu (Environment* ev, const FW_CMenuEvent& event)
- {
- ODCommandID c = event.GetCommandID(ev);
-
- if (fCyberdogHelper) {
- if (c == kDoReload) {
- fCyberdogHelper->GetExtension(ev)->SetCyberItem (ev, fCyberdogHelper->GetCyberItem(ev), kODNULL);
- return FW_kHandled;
- }
- else if (c == kAutoReload) {
- fAutoReload = !fAutoReload;
- return FW_kHandled;
- }
- }
-
- return FW_CPart::DoMenu (ev, event);
- }
-
- #if !USETHREADSFLAG
-
- //----------------------------------------------------------------------------------------
- // CPart::DoIdle
- //----------------------------------------------------------------------------------------
- //
- // CYBERDOG
- //
- // You need to change DoIdle/LoadCyberItem to read your content from the network.
- //
- // DoSetCyberItem is called when you need to read a CyberItem. It starts idling,
- // and you will read the data in DoIdle. If you are using threads (preferred but not
- // quite handled properly by Cyberdog yet), then you will do the work in LoadCyberItem.
- //
- // Note that you must call inherited to get the default behavior of OpenCyberItem as
- // well. Navigator-aware parts will not call inherited but will do things differently.
-
- FW_Boolean CPart::DoIdle (Environment* ev, const FW_CNullEvent& event)
- {
- if (fStream) {
- short status;
- do {
- status = fStream->GetStreamStatus (ev);
- if (status & kCDDataAvailable) {
- Size oldSize = ::GetHandleSize (fDownloadedText);
- FW_CCyberBuffer ab (ev, fStream);
- // CONTENTDATA - change this portion to deal with your data form
- // Add any data available to the text handle, and redraw it
- ::SetHandleSize (fDownloadedText, oldSize + ab.GetSize());
- if (::MemError()) // XXX what's the best way to report an error from an idle method?
- status = kCDErrorOccurred;
- else
- memcpy (*fDownloadedText + oldSize, ab.GetBuffer(), ab.GetSize());
- // Draw the new data right now
- ImmediateRedrawPresentation (ev, fPresentation);
- }
- else if (status & FW_kCyberStreamDone) {
- printf ("DoIdle: done downloading.\n");
- fStream = nil; // smart pointer will call Abort if necessary automatically
- // We can't UnregisterIdle from a DoIdle (OD limitation), so until I figure out a
- // workaround we simply keep on idling (doing nothing).
- //UnregisterIdle (ev);
- printf ("Download time: %i ticks.\n", TickCount()-fStartTime);
- }
- } while (status & kCDDataAvailable);
- }
-
- return false; // let other idlers get time also XXX need FW_kContinueEvent!
- }
-
- #else
-
- //----------------------------------------------------------------------------------------
- // CPart::LoadCyberItem
- //----------------------------------------------------------------------------------------
-
- void CPart::LoadCyberItem (Environment* ev, void* selfCPart)
- {
- // Note this is a static method. "this" is passed in from DoSetCyberItem
- CPart* self = (CPart*) selfCPart;
-
- CyberItem* item = self->fCyberdogHelper->GetCyberItem(ev);
- CyberStream* cStream = item->CreateCyberStream (ev);
- cStream->Open (ev);
- FW_PCyberSink sink (ev, cStream);
-
- // We don't need to deal with error handling at all here. An error causes an
- // exception to be thrown, and all our nice stack-based objects delete themselves.
-
- long total = 0;
- long available;
- while ((available = sink->GetReadableBytes (ev)) != 0) {
- // CONTENTDATA - change this portion to deal with your data form
- // We'll download and display whatever is available.
- ::SetHandleSize (self->fDownloadedText, total + available);
- ::HLock(self->fDownloadedText);
- sink->Read (ev, *self->fDownloadedText + total, available);
- ::HUnlock (self->fDownloadedText);
- total += available;
- // Draw the new data right now
- ImmediateRedrawPresentation (ev, self->fPresentation);
- }
- }
-
- #endif
-
-